I would ike to warn the reader right now that I am a very poor programer, I am sure that there are much easier and faster ways to achieve the objectives of this program than the way I have done it. I learned to program in basic as I was writing this program. The program itself was written in qbasic which came with my version of Ms-Dos 5.00. I had to rely heavily on sequential files to get this program to work because of the 128k enviorment limit on my version of qbasic. I will assume that the reader of this document is famillar with l-systems in my explaniation of the inner workings of the program. I will begin with the 'turtle' interpitation. The sub called turtle handles the drawing of the l-system. It responds to the following commands. The program keeps track of the turtles position in 3-space and also keeps track of the three vectors H, L , and U. which represent the turtles heading, the direction to the Left of the turtle, and the direction up from the turtle respectivly. The turtle responds to the following commands: F(x) : move forward and draw a line x units in the direction of H f(x) : move forward without drawing a line x units in the direction of H +(x) : rotate the turtle by x (in radians) about the U vector. x can be positive or negative depending on the direction wanted. &(x) : rotate the turtle by x (in radians) about the L vector. x can be positive or negative. /(x) : rotate the turtle by x (in radians) about the H vector. x can be positive or negative. [ : stack the current position of the turtle along with the orientation of the turtle. Also stacks current color, line length, line width, and just about everything else that effects the drawing of the object. ] : pull from the stack and make current the orientation, position, color, width, length, and everything else that effects the drawing of the object. !(x): change the width of the lines be drawn to x. $ : roll the turtle so that the L vector fufills the following equation: V X H L = ------- |V X H| then recalulate U so that U = H X L V is the vector pointing opposite to that of gravity. -------------------------------------------------------------------- The turtle orientation is also effected by a tropisim vector T. After every line segment is drawn with F(x) the H vector is rotated slightly in the direction of T. This rotates the turtle about the vector H X T. the angle of rotation is determined by getting the angle alpha between H and T and then rotating the turtle e*alpha degrees. e is a constant that represents how much T effects the turtle. ----------------------------------------------------------------------- < text > : transfer control to the polygon generator and pass the text within the brackets to the polygon generator. when the polygon generator is finished executing the commands stored in the text it restores the turtle information as it was before the call. the polygon generator responds to the following commands { : push the current polygon onto the top of the polygon stack and start a new polygon. * : append the new vertex to the current polygon the coordienits of which are determined by the current position of the turtle. } : Draw the current polygon using the supplied vertices, then pop the top polygon from the polygon stack. F(x): Move forward x units and use the result as the next vetex G(x): Move forward, do not create new vertex This is not yet completly implemented.... ______________________________________________________________________ Everything else in the file being read is ignored. I assume that the reader is famillar with the way that the productions work in l-systems. In this program it is handled by a sub called 'productions'. This does the replacements of the symbols [,],{,},and G along with a few other commands that do not have parameters assioated with them. When it comes to a word that has parameters then it passes control to the sub 'handler' which then passes control to the appropriate sub that replaces it according to the rules within that sub. for example if the program hit A(1,10) then it would pass control to the sub 'handler' which would in turn pass control to the sub A. look at sub A to see how the production works. I had to write my own subs that converted between numeric and string type variables for the parameters since the way qbasics built in conversion routines occasionaly produced strings that had charicters that the program uses to seperate the numbers. For example, if I used the built in numeric to string conversion it would sometimes produce a string that had a comma or ) symbol both of which would cause the getparam sub to think that it was done reading the number in the case of a comma or done reading the parameters in the case of ). I could remedy this problem by using a random access file type but qbasics online help wasn't very helpful in describing the proper use of fields in conjunction with a random access file. Heres a list of the subs and what they do: poly : not currently being used polygon : reads the file 'points.raw' that is produced by the branchman sub, anb creates a raw triangle file for programs such as raw2pov This sub usually produces output that works fine with raw2pov. Unfortunatly when the file size gets large raw2pov aborts with the error 'unexpected end of file' on the last line number of the file generated. I have not found a reason for this. branchman : This sub is called from the turtle sub after every F(x) command. It stack the H and L vectors and creates points on a octogon by rotating L around H 45 degrees 8 times and recording the values in 'points.raw'. tropisim : This sub is called after every F(x). This has alredy been explained above. If you do not want this effect on the object make T()=0 stack(stype$): this sub controls the stacking operation for the [ and ] commands. the array stac() is the stack it controls. rotateX: does the rotation for the $ command. widthman: This sub is called from the turtle sub when the !(x) command is encountered. sets the variable wid to x. wid is used by branchman as a scalar against L to control the width of the branches. rotateU: rotates the turtle about the U vector. rotateL: rotates the turtle about the L vector. rotateH: rotates the turtle about the H vector. trans3d2d: translates the 3d co-ords to 2d co-ords for viewing while turtle draws the initial shape. drawline: draws a line between the old location of the turtle to the new location. called by movef. movef : called by turtle when F(x) or f(x) is encountered in the file being read. If F(x) was passed then drawline is called. if f(x) then drawline is not called number2string(anumber) : converts anumber to number$ getparams : called by a production sub. returns all of the parameters in the way of an array called numberarray. the first valuse in numberarray is the number of parameters in the word being looked at. ie if A(10,1) were encountered by the productions sub control would be passed to the sub A which would in turn call getparams to get the parameters assioated with A. getparams would then return numberarray which would look like: numberarray(1,1) = 2 ; since there are 2 pararmeters numberarray(1,2) = 10 ; value of first parameter numberarray(1,2) = 1 ; value of 2nd parameter this sub also calls string2num to convert the string format to a numeric variable. string2num: (ntemp$) converts ntemp$ to a numeric variable atemp. productions: reads the file Axiom and produces a file called 'commands.raw' for use by the turtle sub. convst: used by num2string handler : used by productions to sort out what it is doing and and where to pass control to. f : production sub for the command F(x) sf : production sub for the command f(x) A : production sub for the command A(x,y) B : production sub for the command B(x,y) cC: production sub for the command C(x,y) D : production sub for the command D(x1,x2,...,xn) RU: production sub for one of the rotate commands RL :' ' RH : ' ' decr: production sub for the !(x) command colour: not yet implemented, but will be a production sub for '(x) where x is the new color to draw in. powercon : used by string2num initial variables: scale : the scale at which the shape is drawn on the screen _ _ _ _ V(1)-V(3): V = V(1)i + V(2)j + V(3)k h(1)-h(3): the inital heading vector H _ _ _ _ H = h(1)i + h(2)j + h(3)k l(1)-l(3): same as above but for the L vector u(1)-u(3): same as above but for the u vector phi: the viewing angle for the shape as it is drawn on string from the positive z-axis th: the viewing angle measured from the x-axis a0 : branching angle from trunk a2 : branching angle from lateral axes r1 : contraction ratio for the trunk r2 : contraction ratio for the branches ds : divergence angle wr : width decrease rate e : the effect of T on the turtle (tropisim) T(1)-T(3): the T vector for tropisim calculations _ _ _ _ T = T(1)i+T(2)j+T(3)k I almost forgot. This program uses axes orientated in the following way : |z | / | / | / --------------+-------------- / | y / | / x | | I hope that this poor description helps whomever is reading this. If you make any changes that speed this program up or add new functions I would be interested in seeing the code. You can contact me via The Graphics Alternative BBS as Ed Smith. P.S. I guess I am placing this code in the public domain. Use it as you see fit. I got most of my ideas for the program for a book called 'The Algorithmic Beauty of plants.' It's a good one. Ed Storm (209)474-9159 May 11, 1993